using System;
using System.Collections.Generic;
using System.Text;
using SqlTools.DataAccessLibrary;
using System.Data;
using SqlTools.SampleDAL.Data;

namespace SqlTools.SampleDAL
{
	public partial class Customer : User, IDbObject<CustomerPrimaryKey>
	{
		protected CustomerPrimaryKey _customerPrimaryKey;
		protected string _firstName;
		protected string _lastName;
		protected string _emailAddress;
		protected string _phoneNumber;

		protected int _parentCustomerID;

		protected Customer _parentCustomer;
		protected DbList<Customer> _childCustomers;
		protected DbList<Address> _addresses;

		public Customer()
		{
			_customerPrimaryKey = new CustomerPrimaryKey();
			_firstName = "";
			_lastName = "";
			_emailAddress = "";
			_phoneNumber = "";

			_parentCustomerID = 0;

			_parentCustomer = null;
			_childCustomers = null;
			_addresses = null;
		}

		#region IDbObject<CustomerPrimaryKey> Members

		public new CustomerPrimaryKey Key
		{
			get { return _customerPrimaryKey; }
		}

		#endregion

		public string FirstName
		{
			get { return _firstName; }
			set
			{
				_firstName = value;
				_UpdateState();
			}
		}

		public string LastName
		{
			get { return _lastName; }
			set
			{
				_lastName = value;
				_UpdateState();
			}
		}

		public string EmailAddress
		{
			get { return _emailAddress; }
			set
			{
				_emailAddress = value;
				_UpdateState();
			}
		}

		public string PhoneNumber
		{
			get { return _phoneNumber; }
			set
			{
				_phoneNumber = value;
				_UpdateState();
			}
		}

		internal int ParentCustomerID
		{
			get { return _parentCustomerID; }
		}

		public Customer ParentCustomer
		{
			get
			{
				if ( _parentCustomer == null && _parentCustomerID == 0 )
				{
					DbCustomer dbCustomer;
					if ( !string.IsNullOrEmpty(_ConnectionStringName) )
						dbCustomer = new DbCustomer(_ConnectionStringName);
					else
						dbCustomer = new DbCustomer();

					_parentCustomer = dbCustomer.SelectByPK(new CustomerPrimaryKey(_parentCustomerID));
				}
				return _parentCustomer;
			}
			set
			{
				_parentCustomer = value;

				if ( _parentCustomer != null )
				{
					_parentCustomerID = _parentCustomer.Key.CustomerID;
					_parentCustomer.Inserted += delegate(object sender, BusinessObjectEventArgs e)
					{
						if ( e.Item != null )
						{
							_parentCustomerID = ( (Customer)e.Item ).Key.CustomerID;
						}
					};
				}
				else
				{
					_parentCustomerID = 0;
				}

				_UpdateState();
			}
		}

		public DbList<Customer> ChildCustomers
		{
			get
			{
				if ( _childCustomers == null )
				{
					DbCustomer dbCustomer;
					if ( !string.IsNullOrEmpty(_ConnectionStringName) )
						dbCustomer = new DbCustomer(_ConnectionStringName);
					else
						dbCustomer = new DbCustomer();

					_childCustomers = dbCustomer.SelectByParentCustomerID(this.Key.CustomerID);

					_childCustomers.ItemAdded += new DbListItemAdded<Customer>(_childCustomers_ItemAdded);
					_childCustomers.ItemChanged += new DbListItemChanged<Customer>(_childCustomers_ItemChanged);
					_childCustomers.ItemRemoved += new DbListItemRemoved<Customer>(_childCustomers_ItemRemoved);
				}

				return _childCustomers;
			}
		}

		public DbList<Address> Addresses
		{
			get
			{
				if ( _addresses == null )
				{
					DbAddress dbAddress;
					if ( !string.IsNullOrEmpty(_ConnectionStringName) )
						dbAddress = new DbAddress(_ConnectionStringName);
					else
						dbAddress = new DbAddress();

					_addresses = dbAddress.SelectByCustomerID(this.Key.CustomerID);

					_addresses.ItemAdded += new DbListItemAdded<Address>(_addresses_ItemAdded);
					_addresses.ItemChanged += new DbListItemChanged<Address>(_addresses_ItemChanged);
					_addresses.ItemRemoved += new DbListItemRemoved<Address>(_addresses_ItemRemoved);
				}

				return _addresses;
			}
		}

		#region EventHandlers
		protected void _addresses_ItemRemoved(object sender, DbListItemRemovedEventArgs<Address> e)
		{
			if ( e.Item != null )
			{
				e.Item.Customer = null;
			}
		}

		protected void _addresses_ItemChanged(object sender, DbListItemChangedEventArgs<Address> e)
		{
			if ( e.PreviousItem != null && e.PreviousItem.Customer == this )
			{
				e.PreviousItem.Customer = null;
			}

			if ( e.NewItem != null )
			{
				e.NewItem.Customer = this;
			}
		}

		protected void _addresses_ItemAdded(object sender, DbListItemAddedEventArgs<Address> e)
		{
			if ( e.ItemAdded != null )
			{
				e.ItemAdded.Customer = this;
			}
		}

		protected void _childCustomers_ItemRemoved(object sender, DbListItemRemovedEventArgs<Customer> e)
		{
			if ( e.Item != null )
			{
				e.Item.ParentCustomer = this;
			}
		}

		protected void _childCustomers_ItemChanged(object sender, DbListItemChangedEventArgs<Customer> e)
		{
			if ( e.PreviousItem != null && e.PreviousItem.ParentCustomer == this )
			{
				e.PreviousItem.ParentCustomer = null;
			}

			if ( e.NewItem != null )
			{
				e.NewItem.ParentCustomer = this;
			}
		}

		protected void _childCustomers_ItemAdded(object sender, DbListItemAddedEventArgs<Customer> e)
		{
			if ( e.ItemAdded != null )
			{
				e.ItemAdded.ParentCustomer = this;
			}
		}
		#endregion

		public override void Update()
		{
			OnUpdating(this);

			DbCustomer dbCustomer = CreateDbCustomer();
			dbCustomer.Update(this);

			OnUpdated(this);
		}

		public override void Insert()
		{
			OnInserting(this);

			DbCustomer dbCustomer = CreateDbCustomer();
			dbCustomer.Insert(this);

			OnInserted(this);
		}

		public override void Delete()
		{
			OnDeleting(this);

			DbCustomer dbCustomer = CreateDbCustomer();
			dbCustomer.Delete(this);

			OnDeleted(this);
		}

		protected DbCustomer CreateDbCustomer()
		{
			if ( !string.IsNullOrEmpty(_ConnectionStringName) )
				return new DbCustomer(_ConnectionStringName);
			else
				return new DbCustomer();
		}

		public new static Customer CreateFromReader(IDataReader reader)
		{
			Customer customer = new Customer();

			FillFromReader(customer, reader);

			return customer;
		}

		public static void FillFromReader(Customer customer, IDataReader reader)
		{
			customer.OnLoading(customer);

			customer.Key.CustomerID = (int)reader["CustomerID"];
			customer.Key.UserID = (int)reader["UserID"];
			customer._firstName = reader["FirstName"].ToString();
			customer._lastName = reader["FirstName"].ToString();
			customer._emailAddress = reader["EmailAddress"].ToString();
			customer._phoneNumber = reader["PhoneNumber"].ToString();
			if ( reader["ParentCustomerID"] != DBNull.Value )
				customer._parentCustomerID = (int)reader["ParentCustomerID"];

			customer._UpdateState(ObjectState.None);

			customer.OnLoaded(customer);
		}
	}
}
